﻿/*************************************************************************
* 计算机名：AA-FA-05
* CLR 版本：4.0.30319.42000
* 命名空间: NModBusDrive
* 类    名：ModBusWrapper
* 当 前 域：HYRC
* 创 建 人：dailuyu
* 创建时间：2021/7/14 19:07:24
* 描    述：
*  V1.0.0.1 初版
*
*  Copyright (c) 2021 aatsr Corporation. All rights reserved.
*  ┌──────────────────────────────────┐
*  │　此技术信息为本公司机密信息，未经本公司书面同意禁止向第三方披露．　│
*  └──────────────────────────────────┘
***************************************************************************/
using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NModBusDrive
{
    public abstract class ModBusWrapper : IDisposable
    {
        public enum Protocol
        {
            TCPIP,
            SerialPort
        }


        public delegate void CallBackData(TEventArgs<DataModel> args);

        private static ModBusWrapper _Instance;
        public static ModBusWrapper CreateInstance(Protocol protocol)
        {
            if (_Instance == null)
            {
                switch (protocol)
                {
                    case Protocol.TCPIP:
                        _Instance = new ModBusTcpWrapper();
                        break;
                    case Protocol.SerialPort:
                        _Instance = new ModBusSerialPortWrapper();
                        break;
                    default:
                        break;
                }
            }
            return _Instance;
        }

        #region Transaction Identifier
        /// <summary>
        /// 数据序号标识
        /// </summary>
        private byte dataIndex = 0;

        protected byte CurrentDataIndex
        {
            get { return this.dataIndex; }
        }

        protected byte NextDataIndex()
        {
            return ++this.dataIndex;
        }
        #endregion
        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="arg1">参数:Ip或者串口号</param>
        /// <param name="port">端口或者波特率</param>
        /// <param name="parity">
        ///   奇偶验证：
        ///      None不发生奇偶校验检查，
        ///      Odd设置奇偶校验位，使位数等于奇数，
        ///      Even设置奇偶校验位，使位数等于偶数，
        ///      Mark将奇偶校验位保留为 1， 
        ///      Space将奇偶校验位保留为 0
        ///    默认为：
        ///      None
        /// </param>
        /// <param name="dataBits">数据位数，默认为 8</param>
        /// <param name="stopBits">
        ///    None不使用停止位,System.IO.Ports.SerialPort.StopBits 属性不支持此值
        ///    One 使用一个停止位
        ///    Two 使用两个停止位
        ///    OnePointFive 使用 1.5 个停止位
        ///</param>
        public abstract void Inin(string arg1, int port, Parity parity = Parity.None, int dataBits = 8, StopBits stopBits = StopBits.One);

        /// <summary>
        /// 连接
        ///   注意：如果出现切换站点出错，可以考虑。每次操作是要开启串口,操作完成后需要关闭串口,目的是为了slave更换连接是否报错
        /// </summary>
        public abstract void Connect();

        /// <summary>
        /// 关闭连接
        /// </summary>
        public abstract void Close();

        /// <summary>
        /// 读线圈
        /// </summary>
        /// <param name="modBusOper">操作方式</param>
        /// <param name="slaveAddress">从站地址</param>
        /// <param name="startAddress">开始地址</param>
        /// <param name="numberOfPoints">数据长度</param>
        public abstract void ReadCoil(ModBusOperType modBusOper,byte slaveAddress=1, ushort startAddress=0, ushort numberOfPoints=0);

        /// <summary>
        /// 写线圈
        /// </summary>
        /// <param name="modBusOper">操作方式</param>
        /// <param name="slaveAddress">从站地址</param>
        /// <param name="startAddress">开始地址</param>
        /// <param name="numberOfPoints">数据长度</param>
        /// <param name="coilsBuffe">写圈</param>
        public abstract void WriteCoil(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0, bool[] coilsBuffer = null);

        /// <summary>
        /// 读寄存器
        /// </summary>
        /// <param name="modBusOper">操作方式</param>
        /// <param name="slaveAddress">从站地址</param>
        /// <param name="startAddress">开始地址</param>
        /// <param name="numberOfPoints">数据长度</param>
        public abstract  void ReadRegister(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0);

        /// <summary>
        /// 写寄存器
        /// </summary>
        /// <param name="modBusOper">操作方式</param>
        /// <param name="slaveAddress">从站地址</param>
        /// <param name="startAddress">开始地址</param>
        /// <param name="numberOfPoints">数据长度</param>
        /// <param name="registerBuffer">写寄存器数组</param>
        public abstract void WriteRegister(ModBusOperType modBusOper, byte slaveAddress = 1, ushort startAddress = 0, ushort numberOfPoints = 0, ushort[] registerBuffer = null);

        public abstract event CallBackData CallBackDataEvent;

        /// <summary>
        /// 日志操作
        /// </summary>
        public ILog Logger { get; set; }



        #region IDisposable 成员
        /// <summary>
        /// 释放资源
        /// </summary>
        public virtual void Dispose()
        {
        }
        #endregion
    }
}
